package com.mettle.loyaltycard.parser;

import java.io.IOException;
import java.text.ParseException;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import junit.framework.Assert;

import org.junit.Test;

import com.mettle.loyaltycard.model.Customer;
import com.mettle.loyaltycard.model.LoyaltyCard;
import com.mettle.loyaltycard.model.MembershipType;

public class InputFileParserTest {

	@Test
	public void testParseLineForUnregisteredCustomer() throws ParseException {
		
		String unregisteredUserTransaction = ",,,5000, 22-06-2012 13:48, 3830283";
		Map<String, LoyaltyCard> loyaltyCards = new HashMap<String, LoyaltyCard>();
		InputFileParser.parseLine(unregisteredUserTransaction, loyaltyCards);
		Assert.assertEquals(0, loyaltyCards.size());
	}
	
	@Test
	public void testParseFile() throws IOException, ParseException {
		Map<String, LoyaltyCard> loyaltyCards = InputFileParser.getCards("/home/abhinav/Desktop/data");
		Collection<LoyaltyCard> loyaltyCardsSet = loyaltyCards.values();
		Assert.assertEquals(5, loyaltyCardsSet.size());
		LoyaltyCard goldLoyaltyCard11003 = loyaltyCards.get("11003");
		testgoldLoyaltyCard11003(goldLoyaltyCard11003);
		LoyaltyCard goldLoyaltyCard11004 = loyaltyCards.get("11004");
		testgoldLoyaltyCard11004(goldLoyaltyCard11004);
		LoyaltyCard loyaltyCard11001 = loyaltyCards.get("11001");
		testLoyaltyCard11001(loyaltyCard11001);
		LoyaltyCard loyaltyCard11002 = loyaltyCards.get("11002");
		testLoyaltyCard11002(loyaltyCard11002);
		LoyaltyCard loyaltyCard11005 = loyaltyCards.get("11005");
		testLoyaltyCard11005(loyaltyCard11005);
	}

	private void testLoyaltyCard11005(LoyaltyCard loyaltyCard11005) {
		Assert.assertEquals(MembershipType.NORMAL, loyaltyCard11005.getMembershipType());
		Assert.assertEquals(17937.0, loyaltyCard11005.getTotalAmount());
		Customer customer = loyaltyCard11005.getCustomer();
		Assert.assertEquals("Abhijeet", customer.getName());
		Assert.assertEquals("abhi@mettl.com", customer.getEmail());
		Assert.assertEquals(Integer.valueOf(100 + 179), loyaltyCard11005.getLoyaltyPoints());
		Assert.assertEquals(1, loyaltyCard11005.getTransactions().size());
	}

	private void testLoyaltyCard11002(LoyaltyCard loyaltyCard11002) {
		Assert.assertEquals(MembershipType.NORMAL, loyaltyCard11002.getMembershipType());
		Assert.assertEquals(3839.0 + 7281.0, loyaltyCard11002.getTotalAmount());
		Customer customer = loyaltyCard11002.getCustomer();
		Assert.assertEquals("Anant", customer.getName());
		Assert.assertEquals("anant@mettl.com", customer.getEmail());
		Assert.assertEquals(Integer.valueOf(100 + 72 + 38), loyaltyCard11002.getLoyaltyPoints());
		Assert.assertEquals(2, loyaltyCard11002.getTransactions().size());
	}

	private void testLoyaltyCard11001(LoyaltyCard loyaltyCard11001) {
		Assert.assertEquals(MembershipType.NORMAL, loyaltyCard11001.getMembershipType());
		Assert.assertEquals(12083.0 + 7402.0, loyaltyCard11001.getTotalAmount());
		Customer customer = loyaltyCard11001.getCustomer();
		Assert.assertEquals("Abhay", customer.getName());
		Assert.assertEquals("abhay@demo.com", customer.getEmail());
		Assert.assertEquals(Integer.valueOf(100 + 74 + 120), loyaltyCard11001.getLoyaltyPoints());
		Assert.assertEquals(2, loyaltyCard11001.getTransactions().size());
	}

	private void testgoldLoyaltyCard11004(LoyaltyCard goldLoyaltyCard) {
		Assert.assertEquals(MembershipType.SILVER, goldLoyaltyCard.getMembershipType());
	Assert.assertEquals(33283.0, goldLoyaltyCard.getTotalAmount());
	Customer customer = goldLoyaltyCard.getCustomer();
	Assert.assertEquals("Abhimanyu", customer.getName());
	Assert.assertEquals("abhi@mettl.com", customer.getEmail());
	Assert.assertEquals(Integer.valueOf(100 + 332), goldLoyaltyCard.getLoyaltyPoints());
	Assert.assertEquals(1, goldLoyaltyCard.getTransactions().size());
	}  

	private void testgoldLoyaltyCard11003(LoyaltyCard silverLoyaltyCard) {
		Assert.assertEquals(MembershipType.GOLD, silverLoyaltyCard.getMembershipType());
		Assert.assertEquals(13890.0 + 38103, silverLoyaltyCard.getTotalAmount());
		Customer customer = silverLoyaltyCard.getCustomer();
		Assert.assertEquals("Ashish", customer.getName());
		Assert.assertEquals("ashish@mettl.com", customer.getEmail());
		Assert.assertEquals(Integer.valueOf(100 + 138 + 381), silverLoyaltyCard.getLoyaltyPoints());
		Assert.assertEquals(2, silverLoyaltyCard.getTransactions().size());

	}
	
	@Test
	public void testParseLineForNewCustomer() throws ParseException {
		
		String newUserTransaction = "Abhay,abhay@demo.com,11001,5000,22-06-2012 13:48,3830283";
		Map<String, LoyaltyCard> loyaltyCards = new HashMap<String, LoyaltyCard>();
		InputFileParser.parseLine(newUserTransaction, loyaltyCards);
		Assert.assertEquals(1, loyaltyCards.size());
		LoyaltyCard loyaltyCard = loyaltyCards.get("11001");
		Customer customer = loyaltyCard.getCustomer();
		Assert.assertEquals("Abhay", customer.getName());
		Assert.assertEquals("abhay@demo.com", customer.getEmail());
	}

	@Test
	public void testGetDate() {
		String testDate = "22-06-2012 11:23";
		Date date = InputFileParser.getDate(testDate);
		Assert.assertEquals(22, date.getDate());
		Assert.assertEquals(5, date.getMonth());
		Assert.assertEquals(112, date.getYear());
		Assert.assertEquals(11, date.getHours());
		Assert.assertEquals(23, date.getMinutes());
	}
	
	@Test(expected=RuntimeException.class)
	public void testGetInvalidDate() {
		String testDate = "abcd";
		InputFileParser.getDate(testDate);
	}
}
